/*
 * Copyright (C) 2005 - 2013 MaNGOS <http://www.getmangos.com/>
 *
 * Copyright (C) 2008 - 2013 Trinity <http://www.trinitycore.org/>
 *
 * Copyright (C) 2006 - 2013 ScriptDev2 <http://www.scriptdev2.com/>
 *
 * Copyright (C) 2010 - 2013 ProjectSkyfire <http://www.projectskyfire.org/>
 *
 * Copyright (C) 2011 - 2013 ArkCORE <http://www.arkania.net/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/* ScriptData
 SDName: GO_Scripts
 SD%Complete: 100
 SDComment: Quest support: 4285, 4287, 4288(crystal pylons), 4296, 6481, 10990, 10991, 10992, Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089, 12843, 12982, 2936. Soulwell
 SDCategory: Game Objects
 EndScriptData */

/* ContentData
 go_cat_figurine (the "trap" version of GO, two different exist)
 go_northern_crystal_pylon
 go_eastern_crystal_pylon
 go_western_crystal_pylon
 go_barov_journal
 go_ethereum_prison
 go_ethereum_stasis
 go_sacred_fire_of_life
 go_shrine_of_the_birds
 go_southfury_moonstone
 go_field_repair_bot_74A
 go_orb_of_command
 go_resonite_cask
 go_tablet_of_madness
 go_tablet_of_the_seven
 go_tele_to_dalaran_crystal
 go_rusty_cage
 go_scourge_cage
 go_jotunheim_cage
 go_table_theka
 go_soulwell
 go_bashir_crystalforge
 EndContentData */

#include "ScriptPCH.h"

/*######
 ## go_cat_figurine
 ######*/

enum eCatFigurine
{
    SPELL_SUMMON_GHOST_SABER = 5968,
};

class go_cat_figurine: public GameObjectScript
{
public:
    go_cat_figurine () :
            GameObjectScript("go_cat_figurine")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject * /*pGO*/)
    {
        pPlayer->CastSpell(pPlayer, SPELL_SUMMON_GHOST_SABER, true);
        return false;
    }
};

/*######
 ## go_crystal_pylons (3x)
 ######*/
class go_northern_crystal_pylon: public GameObjectScript
{
public:
    go_northern_crystal_pylon () :
            GameObjectScript("go_northern_crystal_pylon")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
        {
            pPlayer->PrepareQuestMenu(pGO->GetGUID());
            pPlayer->SendPreparedQuest(pGO->GetGUID());
        }

        if (pPlayer->GetQuestStatus(4285) == QUEST_STATUS_INCOMPLETE)
            pPlayer->AreaExploredOrEventHappens(4285);

        return true;
    }
};

class go_eastern_crystal_pylon: public GameObjectScript
{
public:
    go_eastern_crystal_pylon () :
            GameObjectScript("go_eastern_crystal_pylon")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
        {
            pPlayer->PrepareQuestMenu(pGO->GetGUID());
            pPlayer->SendPreparedQuest(pGO->GetGUID());
        }

        if (pPlayer->GetQuestStatus(4287) == QUEST_STATUS_INCOMPLETE)
            pPlayer->AreaExploredOrEventHappens(4287);

        return true;
    }
};

class go_western_crystal_pylon: public GameObjectScript
{
public:
    go_western_crystal_pylon () :
            GameObjectScript("go_western_crystal_pylon")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
        {
            pPlayer->PrepareQuestMenu(pGO->GetGUID());
            pPlayer->SendPreparedQuest(pGO->GetGUID());
        }

        if (pPlayer->GetQuestStatus(4288) == QUEST_STATUS_INCOMPLETE)
            pPlayer->AreaExploredOrEventHappens(4288);

        return true;
    }
};

/*######
 ## go_barov_journal
 ######*/

class go_barov_journal: public GameObjectScript
{
public:
    go_barov_journal () :
            GameObjectScript("go_barov_journal")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject * /*pGO*/)
    {
        if (pPlayer->HasSkill(SKILL_TAILORING) && pPlayer->GetBaseSkillValue(SKILL_TAILORING) >= 280 && !pPlayer->HasSpell(26086))
        {
            pPlayer->CastSpell(pPlayer, 26095, false);
        }
        return true;
    }
};

/*######
 ## go_field_repair_bot_74A
 ######*/

class go_field_repair_bot_74A: public GameObjectScript
{
public:
    go_field_repair_bot_74A () :
            GameObjectScript("go_field_repair_bot_74A")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject * /*pGO*/)
    {
        if (pPlayer->HasSkill(SKILL_ENGINEERING) && pPlayer->GetBaseSkillValue(SKILL_ENGINEERING) >= 300 && !pPlayer->HasSpell(22704))
        {
            pPlayer->CastSpell(pPlayer, 22864, false);
        }
        return true;
    }
};

/*######
 ## go_gilded_brazier (Paladin First Trail quest (9678))
 ######*/

enum eGildedBrazier
{
    NPC_STILLBLADE = 17716,
};

class go_gilded_brazier: public GameObjectScript
{
public:
    go_gilded_brazier () :
            GameObjectScript("go_gilded_brazier")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
        {
            if (pPlayer->GetQuestStatus(9678) == QUEST_STATUS_INCOMPLETE)
            {
                if (Creature* Stillblade = pPlayer->SummonCreature(NPC_STILLBLADE, 8106.11f, -7542.06f, 151.775f, 3.02598f, TEMPSUMMON_DEAD_DESPAWN, 60000))
                    Stillblade->AI()->AttackStart(pPlayer);
            }
        }
        return true;
    }
};

/*######
 ## go_orb_of_command
 ######*/

class go_orb_of_command: public GameObjectScript
{
public:
    go_orb_of_command () :
            GameObjectScript("go_orb_of_command")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject * /*pGO*/)
    {
        if (pPlayer->GetQuestRewardStatus(7761))
            pPlayer->CastSpell(pPlayer, 23460, true);

        return true;
    }
};

/*######
 ## go_tablet_of_madness
 ######*/

class go_tablet_of_madness: public GameObjectScript
{
public:
    go_tablet_of_madness () :
            GameObjectScript("go_tablet_of_madness")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject * /*pGO*/)
    {
        if (pPlayer->HasSkill(SKILL_ALCHEMY) && pPlayer->GetSkillValue(SKILL_ALCHEMY) >= 300 && !pPlayer->HasSpell(24266))
        {
            pPlayer->CastSpell(pPlayer, 24267, false);
        }
        return true;
    }
};

/*######
 ## go_tablet_of_the_seven
 ######*/

class go_tablet_of_the_seven: public GameObjectScript
{
public:
    go_tablet_of_the_seven () :
            GameObjectScript("go_tablet_of_the_seven")
    {
    }

    //TODO: use gossip option ("Transcript the Tablet") instead, if Trinity adds support.
    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
            return true;

        if (pPlayer->GetQuestStatus(4296) == QUEST_STATUS_INCOMPLETE)
            pPlayer->CastSpell(pPlayer, 15065, false);

        return true;
    }
};

/*#####
 ## go_jump_a_tron
 ######*/

class go_jump_a_tron: public GameObjectScript
{
public:
    go_jump_a_tron () :
            GameObjectScript("go_jump_a_tron")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject * /*pGO*/)
    {
        if (pPlayer->GetQuestStatus(10111) == QUEST_STATUS_INCOMPLETE)
            pPlayer->CastSpell(pPlayer, 33382, true);

        return true;
    }
};

/*######
 ## go_ethereum_prison
 ######*/

enum eEthereumPrison
{
    SPELL_REP_LC = 39456, SPELL_REP_SHAT = 39457, SPELL_REP_CE = 39460, SPELL_REP_CON = 39474, SPELL_REP_KT = 39475, SPELL_REP_SPOR = 39476
};

const uint32 NpcPrisonEntry[] =
{ 22810, 22811, 22812, 22813, 22814, 22815,         //good guys
20783, 20784, 20785, 20786, 20788, 20789, 20790          //bad guys
};

class go_ethereum_prison: public GameObjectScript
{
public:
    go_ethereum_prison () :
            GameObjectScript("go_ethereum_prison")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        int Random = rand() % (sizeof(NpcPrisonEntry) / sizeof(uint32));

        if (Creature* pCreature = pPlayer->SummonCreature(NpcPrisonEntry[Random], pGO->GetPositionX(), pGO->GetPositionY(), pGO->GetPositionZ(), pGO->GetAngle(pPlayer), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
        {
            if (!pCreature->IsHostileTo(pPlayer))
            {
                uint32 Spell = 0;

                if (FactionTemplateEntry const* pFaction = pCreature->getFactionTemplateEntry())
                {
                    switch (pFaction->faction)
                    {
                    case 1011:
                        Spell = SPELL_REP_LC;
                        break;
                    case 935:
                        Spell = SPELL_REP_SHAT;
                        break;
                    case 942:
                        Spell = SPELL_REP_CE;
                        break;
                    case 933:
                        Spell = SPELL_REP_CON;
                        break;
                    case 989:
                        Spell = SPELL_REP_KT;
                        break;
                    case 970:
                        Spell = SPELL_REP_SPOR;
                        break;
                    }

                    if (Spell)
                        pCreature->CastSpell(pPlayer, Spell, false);
                    else
                        sLog->outError("TSCR: go_ethereum_prison summoned Creature (entry %u) but faction (%u) are not expected by script.", pCreature->GetEntry(), pCreature->getFaction());
                }
            }
        }

        return false;
    }
};

/*######
 ## go_ethereum_stasis
 ######*/

const uint32 NpcStasisEntry[] =
{ 22825, 20888, 22827, 22826, 22828 };

class go_ethereum_stasis: public GameObjectScript
{
public:
    go_ethereum_stasis () :
            GameObjectScript("go_ethereum_stasis")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        int Random = rand() % (sizeof(NpcStasisEntry) / sizeof(uint32));

        pPlayer->SummonCreature(NpcStasisEntry[Random], pGO->GetPositionX(), pGO->GetPositionY(), pGO->GetPositionZ(), pGO->GetAngle(pPlayer), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);

        return false;
    }
};

/*######
 ## go_resonite_cask
 ######*/

enum eResoniteCask
{
    NPC_GOGGEROC = 11920
};

class go_resonite_cask: public GameObjectScript
{
public:
    go_resonite_cask () :
            GameObjectScript("go_resonite_cask")
    {
    }

    bool OnGossipHello (Player * /*pPlayer*/, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
            pGO->SummonCreature(NPC_GOGGEROC, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000);

        return false;
    }
};

/*######
 ## go_sacred_fire_of_life
 ######*/

#define NPC_ARIKARA  10882

class go_sacred_fire_of_life: public GameObjectScript
{
public:
    go_sacred_fire_of_life () :
            GameObjectScript("go_sacred_fire_of_life")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
            pPlayer->SummonCreature(NPC_ARIKARA, -5008.338f, -2118.894f, 83.657f, 0.874f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);

        return true;
    }
};

/*######
 ## go_shrine_of_the_birds
 ######*/

enum eShrineOfTheBirds
{
    NPC_HAWK_GUARD = 22992, NPC_EAGLE_GUARD = 22993, NPC_FALCON_GUARD = 22994, GO_SHRINE_HAWK = 185551, GO_SHRINE_EAGLE = 185547, GO_SHRINE_FALCON = 185553
};

class go_shrine_of_the_birds: public GameObjectScript
{
public:
    go_shrine_of_the_birds () :
            GameObjectScript("go_shrine_of_the_birds")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        uint32 BirdEntry = 0;

        float fX, fY, fZ;
        pGO->GetClosePoint(fX, fY, fZ, pGO->GetObjectSize(), INTERACTION_DISTANCE);

        switch (pGO->GetEntry())
        {
        case GO_SHRINE_HAWK:
            BirdEntry = NPC_HAWK_GUARD;
            break;
        case GO_SHRINE_EAGLE:
            BirdEntry = NPC_EAGLE_GUARD;
            break;
        case GO_SHRINE_FALCON:
            BirdEntry = NPC_FALCON_GUARD;
            break;
        }

        if (BirdEntry)
            pPlayer->SummonCreature(BirdEntry, fX, fY, fZ, pGO->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);

        return false;
    }
};

/*######
 ## go_southfury_moonstone
 ######*/

enum eSouthfury
{
    NPC_RIZZLE = 23002, SPELL_BLACKJACK = 39865,         //stuns player
    SPELL_SUMMON_RIZZLE = 39866
};

class go_southfury_moonstone: public GameObjectScript
{
public:
    go_southfury_moonstone () :
            GameObjectScript("go_southfury_moonstone")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject * /*pGO*/)
    {
        //implicitTarget=48 not implemented as of writing this code, and manual summon may be just ok for our purpose
        //pPlayer->CastSpell(pPlayer, SPELL_SUMMON_RIZZLE, false);

        if (Creature* pCreature = pPlayer->SummonCreature(NPC_RIZZLE, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0))
            pCreature->CastSpell(pPlayer, SPELL_BLACKJACK, false);

        return false;
    }
};

/*######
 ## go_tele_to_dalaran_crystal
 ######*/

enum eDalaranCrystal
{
    QUEST_LEARN_LEAVE_RETURN = 12790, QUEST_TELE_CRYSTAL_FLAG = 12845
};

#define GO_TELE_TO_DALARAN_CRYSTAL_FAILED   "This teleport crystal cannot be used until the teleport crystal in Dalaran has been used at least once."
class go_tele_to_dalaran_crystal: public GameObjectScript
{
public:
    go_tele_to_dalaran_crystal () :
            GameObjectScript("go_tele_to_dalaran_crystal")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject * /*pGO*/)
    {
        if (pPlayer->GetQuestRewardStatus(QUEST_TELE_CRYSTAL_FLAG))
        {
            return false;
        }
        else
            pPlayer->GetSession()->SendNotification(GO_TELE_TO_DALARAN_CRYSTAL_FAILED);

        return true;
    }
};

/*######
 ## go_fel_crystalforge
 ######*/

#define GOSSIP_FEL_CRYSTALFORGE_TEXT 31000
#define GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN 31001
#define GOSSIP_FEL_CRYSTALFORGE_ITEM_1 "Purchase 1 Unstable Flask of the Beast for the cost of 10 Apexis Shards"
#define GOSSIP_FEL_CRYSTALFORGE_ITEM_5 "Purchase 5 Unstable Flask of the Beast for the cost of 50 Apexis Shards"
#define GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN "Use the fel crystalforge to make another purchase."

enum eFelCrystalforge
{
    SPELL_CREATE_1_FLASK_OF_BEAST = 40964, SPELL_CREATE_5_FLASK_OF_BEAST = 40965,
};

class go_fel_crystalforge: public GameObjectScript
{
public:
    go_fel_crystalforge () :
            GameObjectScript("go_fel_crystalforge")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) /* != GAMEOBJECT_TYPE_QUESTGIVER) */
            pPlayer->PrepareQuestMenu(pGO->GetGUID()); /* return true*/

        pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
        pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);

        pPlayer->SEND_GOSSIP_MENU(GOSSIP_FEL_CRYSTALFORGE_TEXT, pGO->GetGUID());

        return true;
    }

    bool OnGossipSelect (Player *pPlayer, GameObject *pGO, uint32 /*uiSender*/, uint32 uiAction)
    {
        pPlayer->PlayerTalkClass->ClearMenus();
        switch (uiAction)
        {
        case GOSSIP_ACTION_INFO_DEF:
            pPlayer->CastSpell(pPlayer, SPELL_CREATE_1_FLASK_OF_BEAST, false);
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
            pPlayer->SEND_GOSSIP_MENU(GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN, pGO->GetGUID());
            break;
        case GOSSIP_ACTION_INFO_DEF + 1:
            pPlayer->CastSpell(pPlayer, SPELL_CREATE_5_FLASK_OF_BEAST, false);
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
            pPlayer->SEND_GOSSIP_MENU(GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN, pGO->GetGUID());
            break;
        case GOSSIP_ACTION_INFO_DEF + 2:
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
            pPlayer->SEND_GOSSIP_MENU(GOSSIP_FEL_CRYSTALFORGE_TEXT, pGO->GetGUID());
            break;
        }
        return true;
    }
};

/*######
 ## go_bashir_crystalforge
 ######*/

#define GOSSIP_BASHIR_CRYSTALFORGE_TEXT 31100
#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN 31101
#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1 "Purchase 1 Unstable Flask of the Sorcerer for the cost of 10 Apexis Shards"
#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5 "Purchase 5 Unstable Flask of the Sorcerer for the cost of 50 Apexis Shards"
#define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN "Use the bashir crystalforge to make another purchase."

enum eBashirCrystalforge
{
    SPELL_CREATE_1_FLASK_OF_SORCERER = 40968, SPELL_CREATE_5_FLASK_OF_SORCERER = 40970,
};

class go_bashir_crystalforge: public GameObjectScript
{
public:
    go_bashir_crystalforge () :
            GameObjectScript("go_bashir_crystalforge")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) /* != GAMEOBJECT_TYPE_QUESTGIVER) */
            pPlayer->PrepareQuestMenu(pGO->GetGUID()); /* return true*/

        pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
        pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);

        pPlayer->SEND_GOSSIP_MENU(GOSSIP_BASHIR_CRYSTALFORGE_TEXT, pGO->GetGUID());

        return true;
    }

    bool OnGossipSelect (Player *pPlayer, GameObject *pGO, uint32 /*uiSender*/, uint32 uiAction)
    {
        pPlayer->PlayerTalkClass->ClearMenus();
        switch (uiAction)
        {
        case GOSSIP_ACTION_INFO_DEF:
            pPlayer->CastSpell(pPlayer, SPELL_CREATE_1_FLASK_OF_SORCERER, false);
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
            pPlayer->SEND_GOSSIP_MENU(GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN, pGO->GetGUID());
            break;
        case GOSSIP_ACTION_INFO_DEF + 1:
            pPlayer->CastSpell(pPlayer, SPELL_CREATE_5_FLASK_OF_SORCERER, false);
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
            pPlayer->SEND_GOSSIP_MENU(GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN, pGO->GetGUID());
            break;
        case GOSSIP_ACTION_INFO_DEF + 2:
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
            pPlayer->SEND_GOSSIP_MENU(GOSSIP_BASHIR_CRYSTALFORGE_TEXT, pGO->GetGUID());
            break;
        }
        return true;
    }
};

/*######
 ## matrix_punchograph
 ######*/

enum eMatrixPunchograph
{
    ITEM_WHITE_PUNCH_CARD = 9279, ITEM_YELLOW_PUNCH_CARD = 9280, ITEM_BLUE_PUNCH_CARD = 9282, ITEM_RED_PUNCH_CARD = 9281, ITEM_PRISMATIC_PUNCH_CARD = 9316, SPELL_YELLOW_PUNCH_CARD = 11512, SPELL_BLUE_PUNCH_CARD = 11525, SPELL_RED_PUNCH_CARD = 11528, SPELL_PRISMATIC_PUNCH_CARD = 11545, MATRIX_PUNCHOGRAPH_3005_A = 142345, MATRIX_PUNCHOGRAPH_3005_B = 142475, MATRIX_PUNCHOGRAPH_3005_C = 142476, MATRIX_PUNCHOGRAPH_3005_D = 142696,
};

class go_matrix_punchograph: public GameObjectScript
{
public:
    go_matrix_punchograph () :
            GameObjectScript("go_matrix_punchograph")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        switch (pGO->GetEntry())
        {
        case MATRIX_PUNCHOGRAPH_3005_A:
            if (pPlayer->HasItemCount(ITEM_WHITE_PUNCH_CARD, 1))
            {
                pPlayer->DestroyItemCount(ITEM_WHITE_PUNCH_CARD, 1, true);
                pPlayer->CastSpell(pPlayer, SPELL_YELLOW_PUNCH_CARD, true);
            }
            break;
        case MATRIX_PUNCHOGRAPH_3005_B:
            if (pPlayer->HasItemCount(ITEM_YELLOW_PUNCH_CARD, 1))
            {
                pPlayer->DestroyItemCount(ITEM_YELLOW_PUNCH_CARD, 1, true);
                pPlayer->CastSpell(pPlayer, SPELL_BLUE_PUNCH_CARD, true);
            }
            break;
        case MATRIX_PUNCHOGRAPH_3005_C:
            if (pPlayer->HasItemCount(ITEM_BLUE_PUNCH_CARD, 1))
            {
                pPlayer->DestroyItemCount(ITEM_BLUE_PUNCH_CARD, 1, true);
                pPlayer->CastSpell(pPlayer, SPELL_RED_PUNCH_CARD, true);
            }
            break;
        case MATRIX_PUNCHOGRAPH_3005_D:
            if (pPlayer->HasItemCount(ITEM_RED_PUNCH_CARD, 1))
            {
                pPlayer->DestroyItemCount(ITEM_RED_PUNCH_CARD, 1, true);
                pPlayer->CastSpell(pPlayer, SPELL_PRISMATIC_PUNCH_CARD, true);
            }
            break;
        default:
            break;
        }
        return false;
    }
};

/*######
 ## go_rusty_cage
 ######*/

enum eRustyCage
{
    NPC_GOBLIN_PRISIONER = 29466
};

class go_rusty_cage: public GameObjectScript
{
public:
    go_rusty_cage () :
            GameObjectScript("go_rusty_cage")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (Creature *pGoblinPrisoner = pGO->FindNearestCreature(NPC_GOBLIN_PRISIONER, 5.0f, true))
        {
            pGO->SetGoState(GO_STATE_ACTIVE);
            pPlayer->KilledMonsterCredit(NPC_GOBLIN_PRISIONER, pGoblinPrisoner->GetGUID());
            pGoblinPrisoner->DisappearAndDie();
        }

        return true;
    }
};

/*######
 ## go_scourge_cage
 ######*/

enum eScourgeCage
{
    NPC_SCOURGE_PRISONER = 25610
};

class go_scourge_cage: public GameObjectScript
{
public:
    go_scourge_cage () :
            GameObjectScript("go_scourge_cage")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (Creature *pNearestPrisoner = pGO->FindNearestCreature(NPC_SCOURGE_PRISONER, 5.0f, true))
        {
            pGO->SetGoState(GO_STATE_ACTIVE);
            pPlayer->KilledMonsterCredit(NPC_SCOURGE_PRISONER, pNearestPrisoner->GetGUID());
            pNearestPrisoner->DisappearAndDie();
        }

        return true;
    }
};

/*######
 ## go_arcane_prison
 ######*/

enum eArcanePrison
{
    QUEST_PRISON_BREAK = 11587, SPELL_ARCANE_PRISONER_KILL_CREDIT = 45456
};

class go_arcane_prison: public GameObjectScript
{
public:
    go_arcane_prison () :
            GameObjectScript("go_arcane_prison")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pPlayer->GetQuestStatus(QUEST_PRISON_BREAK) == QUEST_STATUS_INCOMPLETE)
        {
            pGO->SummonCreature(25318, 3485.089844f, 6115.7422188f, 70.966812f, 0, TEMPSUMMON_TIMED_DESPAWN, 60000);
            pPlayer->CastSpell(pPlayer, SPELL_ARCANE_PRISONER_KILL_CREDIT, true);
            return true;
        }
        else
            return false;
    }
};

/*######
 ## go_blood_filled_orb
 ######*/

#define NPC_ZELEMAR  17830

class go_blood_filled_orb: public GameObjectScript
{
public:
    go_blood_filled_orb () :
            GameObjectScript("go_blood_filled_orb")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pGO->GetGoType() == GAMEOBJECT_TYPE_GOOBER)
            pPlayer->SummonCreature(NPC_ZELEMAR, -369.746f, 166.759f, -21.50f, 5.235f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);

        return true;
    }
};

/*######
 ## go_jotunheim_cage
 ######*/

enum eJotunheimCage
{
    NPC_EBON_BLADE_PRISONER_HUMAN = 30186, NPC_EBON_BLADE_PRISONER_NE = 30194, NPC_EBON_BLADE_PRISONER_TROLL = 30196, NPC_EBON_BLADE_PRISONER_ORC = 30195,

    SPELL_SUMMON_BLADE_KNIGHT_H = 56207, SPELL_SUMMON_BLADE_KNIGHT_NE = 56209, SPELL_SUMMON_BLADE_KNIGHT_ORC = 56212, SPELL_SUMMON_BLADE_KNIGHT_TROLL = 56214
};

class go_jotunheim_cage: public GameObjectScript
{
public:
    go_jotunheim_cage () :
            GameObjectScript("go_jotunheim_cage")
    {
    }

    bool OnGossipHello (Player* pPlayer, GameObject* pGO)
    {
        Creature* pPrisoner = pGO->FindNearestCreature(NPC_EBON_BLADE_PRISONER_HUMAN, 5.0f, true);
        if (!pPrisoner)
        {
            pPrisoner = pGO->FindNearestCreature(NPC_EBON_BLADE_PRISONER_TROLL, 5.0f, true);
            if (!pPrisoner)
            {
                pPrisoner = pGO->FindNearestCreature(NPC_EBON_BLADE_PRISONER_ORC, 5.0f, true);
                if (!pPrisoner)
                    pPrisoner = pGO->FindNearestCreature(NPC_EBON_BLADE_PRISONER_NE, 5.0f, true);
            }
        }
        if (!pPrisoner || !pPrisoner->isAlive())
            return false;

        pPrisoner->DisappearAndDie();
        pPlayer->KilledMonsterCredit(NPC_EBON_BLADE_PRISONER_HUMAN, 0);
        switch (pPrisoner->GetEntry())
        {
        case NPC_EBON_BLADE_PRISONER_HUMAN:
            pPlayer->CastSpell(pPlayer, SPELL_SUMMON_BLADE_KNIGHT_H, true);
            break;
        case NPC_EBON_BLADE_PRISONER_NE:
            pPlayer->CastSpell(pPlayer, SPELL_SUMMON_BLADE_KNIGHT_NE, true);
            break;
        case NPC_EBON_BLADE_PRISONER_TROLL:
            pPlayer->CastSpell(pPlayer, SPELL_SUMMON_BLADE_KNIGHT_TROLL, true);
            break;
        case NPC_EBON_BLADE_PRISONER_ORC:
            pPlayer->CastSpell(pPlayer, SPELL_SUMMON_BLADE_KNIGHT_ORC, true);
            break;
        }
        return true;
    }
};

enum eTableTheka
{
    GOSSIP_TABLE_THEKA = 1653,

    QUEST_SPIDER_GOLD = 2936
};

class go_table_theka: public GameObjectScript
{
public:
    go_table_theka () :
            GameObjectScript("go_table_theka")
    {
    }

    bool OnGossipHello (Player* pPlayer, GameObject* pGO)
    {
        if (pPlayer->GetQuestStatus(QUEST_SPIDER_GOLD) == QUEST_STATUS_INCOMPLETE)
            pPlayer->AreaExploredOrEventHappens(QUEST_SPIDER_GOLD);

        pPlayer->SEND_GOSSIP_MENU(GOSSIP_TABLE_THEKA, pGO->GetGUID());

        return true;
    }
};

/*######
 ## go_inconspicuous_landmark
 ######*/

enum eInconspicuousLandmark
{
    SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB = 11462, ITEM_CUERGOS_KEY = 9275,
};

class go_inconspicuous_landmark: public GameObjectScript
{
public:
    go_inconspicuous_landmark () :
            GameObjectScript("go_inconspicuous_landmark")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject* /*pGO*/)
    {
        if (pPlayer->HasItemCount(ITEM_CUERGOS_KEY, 1))
            return false;

        pPlayer->CastSpell(pPlayer, SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB, true);

        return true;
    }
};

/*######
 ## go_soulwell
 ######*/

class go_soulwell: public GameObjectScript
{
public:
    go_soulwell () :
            GameObjectScript("go_soulwell")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject* pGO)
    {
        Unit *caster = pGO->GetOwner();
        if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
            return true;

        if (!pPlayer->IsInSameRaidWith(static_cast<Player *>(caster)))
            return true;

        // Repeating this at every use is ugly and inefficient. But as long as we don't have proper
        // GO scripting with at least On Create and On Update events, the other options are no less
        // ugly and hacky.
        uint32 newSpell = 0;
        if (pGO->GetEntry() == 193169)          // Soulwell for rank 2
        {
            if (caster->HasAura(18693))          // Improved Healthstone rank 2
                newSpell = 58898;
            else if (caster->HasAura(18692))          // Improved Healthstone rank 1
                newSpell = 58896;
            else
                newSpell = 58890;
        }
        else if (pGO->GetEntry() == 181621)          // Soulwell for rank 1
        {
            if (caster->HasAura(18693))          // Improved Healthstone rank 2
                newSpell = 34150;
            else if (caster->HasAura(18692))          // Improved Healthstone rank 1
                newSpell = 34149;
            else
                newSpell = 34130;
        }

        pGO->AddUse();
        pPlayer->CastSpell(pPlayer, newSpell, true);
        return true;
    }
};

/*######
 ## Quest 11255: Prisoners of Wyrmskull
 ## go_dragonflayer_cage
 ######*/

enum ePrisonersOfWyrmskull
{
    QUEST_PRISONERS_OF_WYRMSKULL = 11255, NPC_PRISONER_PRIEST = 24086, NPC_PRISONER_MAGE = 24088, NPC_PRISONER_WARRIOR = 24089, NPC_PRISONER_PALADIN = 24090
};

class go_dragonflayer_cage: public GameObjectScript
{
public:
    go_dragonflayer_cage () :
            GameObjectScript("go_dragonflayer_cage")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pPlayer->GetQuestStatus(QUEST_PRISONERS_OF_WYRMSKULL) != QUEST_STATUS_INCOMPLETE)
            return true;

        Creature* pPrisoner = pGO->FindNearestCreature(NPC_PRISONER_PRIEST, 2.0f);
        if (!pPrisoner)
        {
            pPrisoner = pGO->FindNearestCreature(NPC_PRISONER_MAGE, 2.0f);
            if (!pPrisoner)
            {
                pPrisoner = pGO->FindNearestCreature(NPC_PRISONER_WARRIOR, 2.0f);
                if (!pPrisoner)
                    pPrisoner = pGO->FindNearestCreature(NPC_PRISONER_PALADIN, 2.0f);
            }
        }

        if (!pPrisoner || !pPrisoner->isAlive())
            return true;

        Quest const* qInfo = sObjectMgr->GetQuestTemplate(QUEST_PRISONERS_OF_WYRMSKULL);
        if (qInfo)
        {
            //TODO: prisoner should help player for a short period of time
            pPlayer->KilledMonsterCredit(qInfo->ReqCreatureOrGOId[0], 0);
            pPrisoner->DisappearAndDie();
        }
        return true;
    }
};

/*######
 ## Quest 11560: Oh Noes, the Tadpoles!
 ## go_tadpole_cage
 ######*/

enum eTadpoles
{
    QUEST_OH_NOES_THE_TADPOLES = 11560, NPC_WINTERFIN_TADPOLE = 25201
};

class go_tadpole_cage: public GameObjectScript
{
public:
    go_tadpole_cage () :
            GameObjectScript("go_tadpole_cage")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pPlayer->GetQuestStatus(QUEST_OH_NOES_THE_TADPOLES) == QUEST_STATUS_INCOMPLETE)
        {
            Creature *pTadpole = pGO->FindNearestCreature(NPC_WINTERFIN_TADPOLE, 1.0f);
            if (pTadpole)
            {
                pGO->UseDoorOrButton();
                pTadpole->DisappearAndDie();
                pPlayer->KilledMonsterCredit(NPC_WINTERFIN_TADPOLE, 0);
                //FIX: Summon minion tadpole
            }
        }
        return true;
    }
};

/*######
 ## Quest 14096 & 14142: You've Really Done It This Time, Kul
 ## go_black_cage
 ######*/

enum eReallyDoneItThisTime
{
    QUEST_ALLIANCE_YOU_VE_REALLY_DONE_IT_THIS_TIME_KUL = 14096, QUEST_HORDE_YOU_VE_REALLY_DONE_IT_THIS_TIME_KUL = 14142, NPC_CAPTIVE_ASPIRANT = 34716, NPC_KUL = 34956
};

class go_black_cage: public GameObjectScript
{
public:
    go_black_cage () :
            GameObjectScript("go_black_cage")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if ((pPlayer->GetTeamId() == TEAM_ALLIANCE && pPlayer->GetQuestStatus(QUEST_ALLIANCE_YOU_VE_REALLY_DONE_IT_THIS_TIME_KUL) == QUEST_STATUS_INCOMPLETE) || (pPlayer->GetTeamId() == TEAM_HORDE && pPlayer->GetQuestStatus(QUEST_HORDE_YOU_VE_REALLY_DONE_IT_THIS_TIME_KUL) == QUEST_STATUS_INCOMPLETE))
        {
            Creature *pPrisoner = pGO->FindNearestCreature(NPC_CAPTIVE_ASPIRANT, 1.0f);
            if (!pPrisoner)
                pPrisoner = pGO->FindNearestCreature(NPC_KUL, 1.0f);
            if (pPrisoner)
            {
                pGO->UseDoorOrButton();
                pPrisoner->DisappearAndDie();
                pPlayer->KilledMonsterCredit(pPrisoner->GetEntry(), 0);
            }
        }
        return true;
    }
};

/*######
 ## go_amberpine_outhouse
 ######*/

#define GOSSIP_USE_OUTHOUSE "Use the outhouse."
#define GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND "Quest item Anderhol's Slider Cider not found."

enum eAmberpineOuthouse
{
    ITEM_ANDERHOLS_SLIDER_CIDER = 37247, NPC_OUTHOUSE_BUNNY = 27326, QUEST_DOING_YOUR_DUTY = 12227, SPELL_INDISPOSED = 53017, SPELL_INDISPOSED_III = 48341, SPELL_CREATE_AMBERSEEDS = 48330, GOSSIP_OUTHOUSE_INUSE = 12775, GOSSIP_OUTHOUSE_VACANT = 12779
};

class go_amberpine_outhouse: public GameObjectScript
{
public:
    go_amberpine_outhouse () :
            GameObjectScript("go_amberpine_outhouse")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        QuestStatus status = pPlayer->GetQuestStatus(QUEST_DOING_YOUR_DUTY);
        if (status == QUEST_STATUS_INCOMPLETE || status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_REWARDED)
        {
            pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_USE_OUTHOUSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
            pPlayer->SEND_GOSSIP_MENU(GOSSIP_OUTHOUSE_VACANT, pGO->GetGUID());
            return true;
        }
        else
            pPlayer->SEND_GOSSIP_MENU(GOSSIP_OUTHOUSE_INUSE, pGO->GetGUID());
        return true;
    }

    bool OnGossipSelect (Player *pPlayer, GameObject *pGO, uint32 /*uiSender*/, uint32 uiAction)
    {
        pPlayer->PlayerTalkClass->ClearMenus();
        if (uiAction == GOSSIP_ACTION_INFO_DEF + 1)
        {
            pPlayer->CLOSE_GOSSIP_MENU();
            Creature* pTarget = GetClosestCreatureWithEntry(pPlayer, NPC_OUTHOUSE_BUNNY, 3.0f);
            if (pTarget)
            {
                pTarget->AI()->SetData(1, pPlayer->getGender());
                pGO->CastSpell(pTarget, SPELL_INDISPOSED_III);
            }
            pGO->CastSpell(pPlayer, SPELL_INDISPOSED);
            if (pPlayer->HasItemCount(ITEM_ANDERHOLS_SLIDER_CIDER, 1))
                pGO->CastSpell(pPlayer, SPELL_CREATE_AMBERSEEDS);
            return true;
        }
        else
        {
            pPlayer->CLOSE_GOSSIP_MENU();
            pPlayer->GetSession()->SendNotification(GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND);
            return false;
        }
    }
};

/*######
 ## Quest 1126: Hive in the Tower
 ######*/

enum eHives
{
    QUEST_HIVE_IN_THE_TOWER = 9544, NPC_HIVE_AMBUSHER = 13301
};

class go_hive_pod: public GameObjectScript
{
public:
    go_hive_pod () :
            GameObjectScript("go_hive_pod")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        pPlayer->SendLoot(pGO->GetGUID(), LOOT_CORPSE);
        pGO->SummonCreature(NPC_HIVE_AMBUSHER, pGO->GetPositionX() + 1, pGO->GetPositionY(), pGO->GetPositionZ(), pGO->GetAngle(pPlayer), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
        pGO->SummonCreature(NPC_HIVE_AMBUSHER, pGO->GetPositionX(), pGO->GetPositionY() + 1, pGO->GetPositionZ(), pGO->GetAngle(pPlayer), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
        return true;
    }
};

class go_massive_seaforium_charge: public GameObjectScript
{
public:
    go_massive_seaforium_charge () :
            GameObjectScript("go_massive_seaforium_charge")
    {
    }

    bool OnGossipHello (Player* /*pPlayer*/, GameObject *pGo)
    {
        pGo->SetLootState(GO_JUST_DEACTIVATED);
        return true;
    }
};

/*######
 ## Quest 14474 & 14001 : Goblin Escape Pods
 ######*/

#define QUESTA       14474
#define QUESTB       14001
#define KILLCREDIT   34748
#define LIVESPAWN	 66137
#define DEADSPAWN	 66138
#define GALLWIX		 67845

class go_goblincscapepod : public GameObjectScript
{
	public:
    go_goblincscapepod() : GameObjectScript("go_goblincscapepod") { }

bool OnGossipHello(Player* player, GameObject* pGO)
{
    if ((player->GetQuestStatus(QUESTA) == QUEST_STATUS_INCOMPLETE)	|| (player->GetQuestStatus(QUESTB) == QUEST_STATUS_INCOMPLETE))
    {
		//TODO
		// First time you shoud get spell GALLWIX cast and this NPC has some speahc todo about ripping player off

		uint8 r = rand() % 8;
		if (r < 2) //sometimes sapwn a dead goblin and dont give credit..
			player->CastSpell(player, DEADSPAWN, true);
		else
		{
			player->CastSpell(player, LIVESPAWN, true);
			player->KilledMonsterCredit(KILLCREDIT,0);
		}
		pGO->Delete();
		return false;
    }
    return true;
}

};

/*######
## Quest 14124: Liberate the Kaja'mite
######*/
#define LTKQUEST       		14124
#define KAJAMITECHUNK       195492 //Gameobject
#define KABLOOEYBOMBSSPELL	67682 // Spell
#define KABLOOEYBOMBSITEM	48768 // Item

class go_kajamitedeposit : public GameObjectScript
{
	public:
    go_kajamitedeposit() : GameObjectScript("go_kajamitedeposit") { }

	bool OnGossipHello(Player* player, GameObject* pGO)
	{
    if (player->GetQuestStatus(LTKQUEST) == QUEST_STATUS_INCOMPLETE && player->HasItemCount(KABLOOEYBOMBSITEM, 1))
		{
			player->CastSpell(player, KABLOOEYBOMBSSPELL, true);
			pGO->SummonGameObject(KAJAMITECHUNK, pGO->GetPositionX(), pGO->GetPositionY(), pGO->GetPositionZ(), 0, 0 ,0 ,0 ,0 ,300);
			uint8 r = rand() % 3; // add some random spawn locations and a random spawn count
			if (r < 2)
				pGO->SummonGameObject(KAJAMITECHUNK, pGO->GetPositionX()+1, pGO->GetPositionY()+1, pGO->GetPositionZ(), 0, 0 ,0 ,0 ,0 ,300);
			if (r > 1)
				pGO->SummonGameObject(KAJAMITECHUNK, pGO->GetPositionX()-1, pGO->GetPositionY()-1, pGO->GetPositionZ(), 0, 0 ,0 ,0 ,0 ,300);
			
			pGO->Delete();
			return false;
		}
    return true;
	}

};

/*######
## Quest 14124: Up, Up & Away!
######
*/
#define UUAAGOSSIP_GOFLY		"Up, Up & Away!"
#define UUAAQUEST       		14244
#define UUAAKILLCREDIT      	50046
#define UUAA_EXPLODE_SPELL		66127
#define UUAA_SUMMON_ROCKET		68806 // this procs 68804

// search for " Up, Up & Away! " in spellwork

class go_rocketsling: public GameObjectScript
{
	public:
    go_rocketsling() : GameObjectScript("go_rocketsling") { }

	bool OnGossipHello(Player* player, GameObject* pGO)
	{
		 if (player->GetQuestStatus(UUAAQUEST) == QUEST_STATUS_INCOMPLETE)
		 {
			 player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, UUAAGOSSIP_GOFLY  ,GOSSIP_SENDER_MAIN ,GOSSIP_ACTION_INFO_DEF+1);
		 }
		 player->PlayerTalkClass->SendGossipMenu(907, pGO->GetGUID());
   
    return true;
	}

	bool OnGossipSelect(Player* player, GameObject* pGO, uint32 /*sender*/, uint32 action)
	{
		player->PlayerTalkClass->ClearMenus();
		switch(action - GOSSIP_ACTION_INFO_DEF)
		{
			case 1:
				{
					player->CLOSE_GOSSIP_MENU();
					// the teleport can be removed once i complete this
					// todo:
					// mount player
					// auto fly player on mount in a arc over river to TP location bellow
					// at end of flight do kill credit
					// explode rcoket
					player->TeleportTo(648, 946.01f, 2397.09f, 2.38f, 4.4f);
					player->KilledMonsterCredit(UUAAKILLCREDIT,0);
					return false;
				}
		}
		return true;
	}

};

/*######
## Quest 14245: It's a Town-In-A-Box
######
*/
#define	TIABQUEST			14245
#define TIABPLUNGERSPELL	68938  // gives kill credit and via spell_link_spell chnages phase to 2048
// #define TIABSMOKESPELL		71094  // removed in spell_link_spell
#define SMOKEBUNNYNPC		38069
class go_towninabox : public GameObjectScript
{
	public:
    go_towninabox() : GameObjectScript("go_towninabox") { }

	bool OnGossipHello(Player* player, GameObject* pGO)
	{
    if (player->GetQuestStatus(TIABQUEST) == QUEST_STATUS_INCOMPLETE)
		{
			pGO->SummonCreature(SMOKEBUNNYNPC, pGO->GetPositionX(), pGO->GetPositionY(), pGO->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
			player->CastSpell(player, TIABPLUNGERSPELL, true);
			player->KilledMonsterCredit(UUAAKILLCREDIT,0);
			return false;
		}
    return true;
	}

};

/*######
 ## go_gnoll_cage
 ######*/

enum eGnollCage
{
    NPC_GNOLL_PRISIONER = 41410,
	GNOLL_QUEST_KILL_CREDIT = 41438,
	GNOLL_ESCAPE_QUEST = 25867
};

class go_gnoll_cage: public GameObjectScript
{
public:
    go_gnoll_cage () :
            GameObjectScript("go_gnoll_cage")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pPlayer->GetQuestStatus(GNOLL_ESCAPE_QUEST) == QUEST_STATUS_INCOMPLETE)
		{
			if (Creature *pGnollPrisoner = pGO->FindNearestCreature(NPC_GNOLL_PRISIONER, 5.0f, true))
			{
				pGO->SetGoState(GO_STATE_ACTIVE);
				pPlayer->KilledMonsterCredit(GNOLL_QUEST_KILL_CREDIT, 0);
				pGnollPrisoner->DisappearAndDie();
			}
		}
        return true;
    }
};

/*######
 ## go_cultist_cage
 ######*/
// NOT SURE IF THIS IS 100% BLIZZ LIKE CANT FIND ANY DATA ON THIS QUEST
// http://www.wowhead.com/quest=26955
enum eCultistCage
{
    NPC_CAGED_BEAR  = 44902,
	NPC_ZENKIKI     = 44863,
	SPELL_HEAL_BEAR = 8070,
	ZKATC_QUEST = 26955
};

class go_cultist_cage: public GameObjectScript
{
public:
    go_cultist_cage () :
            GameObjectScript("go_cultist_cage")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pPlayer->GetQuestStatus(ZKATC_QUEST) == QUEST_STATUS_INCOMPLETE)
		{
			if (Creature *pCagedBear = pGO->FindNearestCreature(NPC_CAGED_BEAR, 8.0f, true))
			{
				pGO->SetGoState(GO_STATE_ACTIVE);
				Creature * pVenKiki = pGO->SummonCreature(NPC_ZENKIKI, pPlayer->GetPositionX()-2, pPlayer->GetPositionY()+2, pPlayer->GetPositionZ(), pPlayer->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 12000);
				if (pVenKiki)
					pVenKiki->CastSpell(pCagedBear,SPELL_HEAL_BEAR,true);
			}
		}

        return true;
    }
};

/*######
 ## go_blackhoof_cage
 ## http://www.wowhead.com/quest=27245
 ######*/

enum eBackhoofCage
{
    NPC_THERAMORE_PRISIONER = 23720,
	BH_QUEST_KILL_CREDIT = 23720,
    POTG_QUEST = 27245
};

class go_blackhoof_cage: public GameObjectScript
{
public:
    go_blackhoof_cage () :
            GameObjectScript("go_blackhoof_cage")
    {
    }

    bool OnGossipHello (Player *pPlayer, GameObject *pGO)
    {
        if (pPlayer->GetQuestStatus(POTG_QUEST) == QUEST_STATUS_INCOMPLETE)
		{
            if (Creature *pTheramorePrisoner = pGO->FindNearestCreature(NPC_THERAMORE_PRISIONER, 5.0f, true))
            {
                pGO->SetGoState(GO_STATE_ACTIVE);
                pPlayer->KilledMonsterCredit(BH_QUEST_KILL_CREDIT, 0);
                pTheramorePrisoner->DisappearAndDie();
            }
        }
        return true;
    }
};


void AddSC_go_scripts ()
{
    new go_cat_figurine;
    new go_northern_crystal_pylon;
    new go_eastern_crystal_pylon;
    new go_western_crystal_pylon;
    new go_barov_journal;
    new go_field_repair_bot_74A;
    new go_gilded_brazier;
    new go_orb_of_command;
    new go_shrine_of_the_birds;
    new go_southfury_moonstone;
    new go_tablet_of_madness;
    new go_tablet_of_the_seven;
    new go_jump_a_tron;
    new go_ethereum_prison;
    new go_ethereum_stasis;
    new go_resonite_cask;
    new go_sacred_fire_of_life;
    new go_tele_to_dalaran_crystal;
    new go_fel_crystalforge;
    new go_bashir_crystalforge;
    new go_matrix_punchograph;
    new go_rusty_cage;
    new go_scourge_cage;
    new go_arcane_prison;
    new go_blood_filled_orb;
    new go_jotunheim_cage;
    new go_table_theka;
    new go_inconspicuous_landmark;
    new go_soulwell;
    new go_tadpole_cage;
    new go_dragonflayer_cage;
    new go_black_cage;
    new go_amberpine_outhouse;
    new go_hive_pod;
    new go_massive_seaforium_charge;
	new go_goblincscapepod;
	new go_kajamitedeposit;
	new go_rocketsling;
	new go_towninabox;
    new go_gnoll_cage;
	new go_cultist_cage;
    new go_blackhoof_cage;
}
